package discard.kv;

import java.util.concurrent.atomic.AtomicInteger;
import hyl.core.MyFun;
import hyl.core.data.ICache;

/**
 * 核心思想是把map 定时缓存到redis中
 * 
 * 并实现过期 处理
 * 
 * 定时提交 在ConfigCache 中实现
 * 
 * @param <T>
 */
public abstract class ACache<T> implements ICache {
// 内存中缓存 group,Object

	protected Long _expirems = 0L;// 过期时间 (毫秒) 大于过期时间的缓存自动清除所有数据
	protected Long _timestamp = 0L;// 当前活动时间戳 根据当前时间戳来计算空闲时长
	protected T _group = null;// 缓存分组
	protected ConfigCache _rc;// 配置
	// 每组数据最大保存键值对条数(适用于list set 和 queue)
	protected AtomicInteger _kcount = new AtomicInteger(0);

	/** 从Cache.json文件中读取配置文件 */
	protected  ConfigCache getConfig(String alias) {
		ConfigCache cc = ConfigPool.getInstance().getCacheConfig(alias);
		if (cc == null) {
			System.out.println(" ConfigCache 不能识别Cache.json配置中的" + alias);
		}
		return cc;
	}

	// 初始化
	protected void ini(ConfigCache  config) {
		_rc = config;
		config.AddCache(this);
		_expirems = config.EXPIRE_MS;
		_timestamp = MyFun.getMs();
	}

	/**
	 * 设置 过期时间 (毫秒) <br>
	 * 大于过期时间的缓存自动清除
	 * 
	 */
	public void setExpirems(Long expirems) {
		_expirems = expirems;
	}

	/**
	 * 一开始必须读取一个组<br>
	 * 初始化时使用
	 */
	public void open(String group) throws Exception {
		if (MyFun.isEmpty(group)) {
			throw new Exception("open(group) 的入参 group值 不能为空");
		}
	}

	/**
	 * 如果有行为 那么延迟清除缓存，（可用可不用）
	 */
	public void delay() {
		_timestamp = MyFun.getMs();
	}

	/**
	 * 空闲时间 大于过期时间的缓存自动清除
	 * 
	 * expire() 自动触发和手动触发两种
	 */
	public void expire() {
		// 如果没有过期常数 不处理
		if (_expirems <= 0)
			return;
		// 如果有过期常数，超过常数的进行处理
		Long l = MyFun.getMs();
		if (_timestamp == 0) {
			_timestamp = l;
			return;
		}
		long i = l - _timestamp;

		// 如果超期删除整组数据
		if (i > _expirems) {
			_timestamp = l;
			// System.out.println("expire() 已超时=" + (l - _timestamp));
			clear();
		}

	}

	public abstract void clear();
	public void close() {
		_rc.close();
	}
}
